package com.cxm.report.service.impl;

import com.cxm.report.dao.EfficiencyReportDao;
import com.cxm.report.model.IReport;
import com.cxm.report.model.criteria.ReportFilter;
import com.cxm.report.model.data.EfficiencyReport;
import com.cxm.report.model.data.Report;
import com.cxm.report.service.EfficiencyReportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author scl.BlueOcean
 * @version 1.0
 * @date 2018年08月13 16:56
 * @description
 */
@Service
public class EffiencyReportServiceImpl extends AbstractReportService implements EfficiencyReportService {
    @Autowired
    private EfficiencyReportDao efficiencyReportDao;
    @Override
    public void refreshData(String date) {
        efficiencyReportDao.delete(date);
        efficiencyReportDao.batchInsert(date);
    }
    @Override
    public List<Report> dayReport(ReportFilter filter) {
        List<EfficiencyReport> efficiencyReports = efficiencyReportDao.selectDayReports(filter);

        return getReports(efficiencyReports);
    }

    private List<Report> getReports(List<EfficiencyReport> efficiencyReports) {
        List<Report> reports = new ArrayList<>();
        //按照日期分组统计
        Map<String, List<EfficiencyReport>> reportGroup = groupReportData(efficiencyReports);
        //按日期生成报告
        for (Map.Entry<String, List<EfficiencyReport>> reportEntry : reportGroup.entrySet()) {
            generateReport(reports,reportEntry.getKey(), reportEntry.getValue());
        }
        return reports;
    }

    private void generateReport(List<Report> reports,String date, List<EfficiencyReport> reportDetails) {
        Report report = new Report();
        report.setType(IReport.Type.EFFICIENCY);
        report.setDate(date);
        filledTimeScope(reportDetails);
        report.setTotal(caculateTotal(reportDetails));
        report.setDetails(reportDetails);
        reports.add(report);
    }

    /**
     * 填充没有的范围名
     * @param reportDetails
     */
    private void filledTimeScope(List<EfficiencyReport> reportDetails) {
        Set<String> timeScopes = reportDetails.stream().map(EfficiencyReport::getTimeScope).collect(Collectors.toSet());
        for (int i = 0; i < EfficiencyReport.timeGroup.length; i++) {
            String timeScope = EfficiencyReport.timeGroup[i];
            if (!timeScopes.contains(timeScope)){
                EfficiencyReport reportDetail = new EfficiencyReport(timeScope);
                reportDetails.add(i,reportDetail);
            }
        }
    }

    /**
     * 计算合计
     * @param details
     * @return
     */
    private EfficiencyReport caculateTotal(List<EfficiencyReport> details) {
        return details.stream().reduce(new EfficiencyReport(),(x, y)->{
            x.setCount(x.getCount()+y.getCount());
            return x;
        });
    }
    @Override
    public List<Report> timeScopeReport(ReportFilter filter) {
        List<Report> reports = new ArrayList<>();
        List<EfficiencyReport> efficiencyReports = efficiencyReportDao.selectReportsOfScope(filter);
        generateReport(reports,String.format("%s～%s",filter.getBegin(),filter.getEnd()),efficiencyReports);
        return reports;
    }

    @Override
    public List<Report> monthReport(ReportFilter filter) {
        List<EfficiencyReport> efficiencyReports = efficiencyReportDao.selectReportsGroupMonth(filter);
        return getReports(efficiencyReports);
    }

    @Override
    public List<Report> weekReport(ReportFilter filter) {
        List<EfficiencyReport> efficiencyReports = efficiencyReportDao.selectReportsGroupWeek(filter);
        List<Report> reports = getReports(efficiencyReports);
        setFirstAndLast(reports,filter);
        return reports;
    }


    private Map<String, List<EfficiencyReport>> groupReportData(List<EfficiencyReport> efficiencyReports) {
        return efficiencyReports.stream().collect(Collectors.groupingBy(EfficiencyReport::getReportDate, LinkedHashMap::new,Collectors.toList()));
    }
}
